﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Globalization;
using System.Threading;
using MvcCarConsume.Domain;
using System.Configuration;

namespace MvcCarConsume.WebUI
{
    public class BaseController : Controller
    {
        protected IStatictics staticticsService;
        protected string redirectUrl;

        public BaseController()
        {
            this.staticticsService = ServiceFactory.GetStatictcsService(ConfigurationManager.ConnectionStrings["MvcCarDBEntities"].ConnectionString);
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (staticticsService != null)
            {
                ////对于子页和因为全球化框架造成的重定向不计算
                if (!ControllerContext.IsChildAction && string.IsNullOrEmpty(redirectUrl))
                {
                    string controller = filterContext.Controller.GetType().Name;
                    string action = filterContext.ActionDescriptor.ActionName;
                    staticticsService.AddAction(controller, action);
                }
            }
            base.OnActionExecuting(filterContext);
        }

        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            base.Initialize(requestContext);
            object cultureValue;
            if (requestContext.RouteData.Values.TryGetValue("ci", out cultureValue))
            {
                try
                {
                    Thread.CurrentThread.CurrentUICulture = CultureProvider.GetCultureInfo(cultureValue.ToString());
                    Thread.CurrentThread.CurrentCulture = CultureProvider.GetCultureInfo(cultureValue.ToString());
                    Response.Cookies.Add(new HttpCookie(CultureProvider.culturecookiekey,cultureValue.ToString().ToLower()));
                }
                catch { throw new Exception("Culture Error!"); }
            }
            else
            {
                //check cookie
                HttpCookie cLang = requestContext.HttpContext.Request.Cookies[CultureProvider.culturecookiekey];
                if (cLang != null)
                {
                    cultureValue = cLang.Value;
                }
                else //check brower setting
                {
                    string[] langs = requestContext.HttpContext.Request.UserLanguages;
                    if (langs != null && langs.Length > 0)
                    {
                        cultureValue = langs[0].Split(';').First();
                    }
                }

                if (cultureValue == null)
                {
                    cultureValue = CultureProvider.culturedefault;
                }
                //redirect TODO: if form infomation will loose??????
                redirectUrl = string.Format(@"/{0}{1}",
                    cultureValue.ToString().ToLower(),
                    requestContext.HttpContext.Request.RawUrl);

            }
        }

        protected override IActionInvoker CreateActionInvoker()
        {
            return new CustomControllerActionInvoker(redirectUrl);
        }
    }

    internal class CustomControllerActionInvoker : ControllerActionInvoker
    {
        string redirectUrl;
        public CustomControllerActionInvoker(string url)
            : base()
        {
            redirectUrl = url;
        }
        protected override ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
        {
            object returnValue;
            if (!string.IsNullOrEmpty(redirectUrl) && !controllerContext.IsChildAction)
                returnValue = new RedirectResult(redirectUrl);
            else
                returnValue = actionDescriptor.Execute(controllerContext, parameters);
            ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
            return result;
        }
    }

}